package com.db.jdbc;


import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ignite.Ignition;
import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.configuration.ClientConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

/**
 * JDBC连接工具类
 *
 * @author ：Bruce
 * @date ：Created in 2019/12/10 22:21
 */
@Slf4j
public class JdbcUtils {

    /** 数据库连接地址 */
    public static final String URL = "url";

    /** 数据库用户名 */
    public static final String USER = "user";

    /** 数据库密码 */
    public static final String PASSWORD = "password";

    private JdbcUtils() {
        throw new IllegalAccessError();
    }


    /**
     * 读取db.properties配置文件建立Jdbc连接
     *
     * @return Connection
     */
    public static Connection buildConnection() {
        try {
            // 加载db.properties配置文件
            InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(in);
            return buildConnection(properties);
        } catch (IOException e) {
            throw new SqlConnectionException("failed to build connection from db.properties!", e);
        }
    }

    /**
     * 根据Properties建立Jdbc连接
     * properties 至少包括 "url"、"user" 和 "password"
     *
     * @return Connection
     */
    public static Connection buildConnection(Properties properties) {
        if (!validProperties(properties)) {
            throw new SqlConnectionException("jdbc properties must include user and password.");
        }

        Connection connection;
        try {
            String url = properties.getProperty(URL);
            Class.forName(DbDriverMapper.getDriverClassName(url));
            connection = DriverManager.getConnection(url, properties);
        } catch (Exception e) {
            throw new SqlConnectionException("failed to build connection - {}", e.getMessage());
        }
        return connection;
    }

    /**
     * 根据Properties建立Jdbc连接
     * properties 至少包括"user" 和 "password"
     *
     * @return Connection
     */
    public static Connection buildConnection(String url, Properties properties) {
        if (!validProperties(properties)) {
            throw new SqlConnectionException("jdbc properties must include user and password.");
        }

        Connection connection;
        try {
            Class.forName(DbDriverMapper.getDriverClassName(url));
            connection = DriverManager.getConnection(url, properties);
        } catch (Exception e) {
            throw new SqlConnectionException("failed to build connection - {}", e.getMessage());
        }
        return connection;
    }

    /**
     * 获取数据库连接,根据url自动识别建立的数据库连接类型
     *
     * @param url      url
     * @param username username
     * @param password password
     * @return Connection
     */
    public static Connection buildConnection(String url, String username, String password) {
        if (!validJdbcProp(url, username, password)) {
            throw new SqlConnectionException("jdbc url user password can not be empty");
        }
        try {
            Class.forName(DbDriverMapper.getDriverClassName(url));
            return DriverManager.getConnection(url, username, password);
        } catch (Exception e) {
            throw new SqlConnectionException("failed to build connection - {}", e.getMessage());
        }
    }

    /**
     * 获取Ignite 数据库连接
     *
     * @param url      数据库连接地址
     * @param username 用户名
     * @param password 密码
     * @return
     */
    public static IgniteClient buildIgniteConnection(String url, String username, String password) {
        ClientConfiguration cfg = new ClientConfiguration()
                .setAddresses(url)
                .setUserName(username)
                .setUserPassword(password);
        return Ignition.startClient(cfg);
    }

    /**
     * 验证jdbc properties 文件
     *
     * @param properties properties
     */
    private static boolean validProperties(Properties properties) {
        return properties != null && properties.containsKey(USER) && properties.containsKey(PASSWORD);
    }

    /**
     * Jdbc属性验证
     *
     * @return jdbc属性是否完整
     */
    private static boolean validJdbcProp(String url, String user, String password) {
        return !StrUtil.hasBlank(url, user, password);
    }

    /**
     * 关闭所有
     *
     * @param autoCloseables 需关闭对象
     */
    public static void close(AutoCloseable... autoCloseables) {
        for (AutoCloseable autoCloseable : autoCloseables) {
            if (autoCloseable != null) {
                try {
                    autoCloseable.close();
                } catch (Exception e) {
                    log.error("close error", e);
                }
            }
        }
    }
}
